import groovy.util.XmlSlurper

import org.springframework.core.io.DefaultResourceLoader as DRL
import org.springframework.util.StringUtils

import org.apache.commons.io.IOUtils
import org.apache.commons.codec.digest.DigestUtils

import org.w3c.tidy.Tidy

def ANT = new AntBuilder()

def shortcuts = [
	spring : "org/springframework/spring"
]

def baseUrl = "http://repo1.maven.org/maven2"

def jarName
def version

if (this.args.size() >= 1) {
	jarName = this.args[0]
}

if (this.args.size() >= 2) {
	version = this.args[1]
}

if (!StringUtils.hasText(jarName)) {
	throw new IllegalArgumentException("JAR name is required")
}

def realJarName
def canonicalJarName

if (shortcuts."${jarName}") {
	realJarName = shortcuts."${jarName}"
	canonicalJarName = jarName
} else {
	if (jarName.indexOf("/") < 0) {
		realJarName = "${jarName}/${jarName}"
		canonicalJarName = jarName
	} else {
		realJarName = jarName
		def tokens = realJarName.tokenize("/")
		canonicalJarName = tokens[tokens.size() - 1]
	}
}

def drl = new DRL()

def jarBaseUrl = "${baseUrl}/${realJarName}"


if (!version) {
	def htmlResource = drl.getResource("${jarBaseUrl}")

	def tidy = new Tidy()
	tidy.xHTML = true
	tidy.quiet = true
	tidy.showWarnings = false
	def stringWriter = new StringWriter()
	tidy.parse(htmlResource.inputStream, stringWriter)
		
	def html = new XmlSlurper().parseText(stringWriter.toString())

	def versions = []

	html.body.pre.a.each {
		def href = it.@href.text()
		def text = it.text()
		text = text.substring(1, text.length())
				
		if (href == text && !href.startsWith("maven-metadata")) {
			versions.add(text.substring(0, text.length() - 1))
		}
	}

	println("No version specified. Please select your version below:")
	def counter = 0
	versions.each {
		println("${++counter}. ${it}")
	}
	println("")
	ANT.input(message: "Enter version id or enter to quit:", addProperty: "version.id")
	def versionIdString = ANT.antProject.properties."version.id"
	def versionId
	if (versionIdString) {
		versionId = versionIdString.toInteger()
	} else {
		println("Quitting ...")
		System.exit(1)
	}
	if (versionId < 0 || versionId > versions.size()) {
		throw new IllegalArgumentException("Illegal version id [${versionId}]")
	} else {
		version = versions.get(versionId - 1)
	}
}

// Trying to fetch version directory
def version_directory_baseUrl = "${jarBaseUrl}/${version}"
def version_directory_resource = drl.getResource(version_directory_baseUrl)

try {
	IOUtils.toString(version_directory_resource.inputStream)
} catch (FileNotFoundException e) {
	println("Could not get [${canonicalJarName}] version [${version}]. See details below:")
	println("If you're behind a firewall try to set proxy host and port using:")
	println("   set JAVA_OPTS=-DproxyHost=<proxy_host> -DproxyPort=<proxy_port>")
	throw e
}

// We could read the HTML for the version that's been selected. Hurray!
// Going to read the jar file now

def jar_file_url = "${version_directory_baseUrl}/${canonicalJarName}-${version}.jar"
def jar_md5_url = "${version_directory_baseUrl}/${canonicalJarName}-${version}.jar.md5"
def src_file_url = "${version_directory_baseUrl}/${canonicalJarName}-${version}-sources.jar"
def src_md5_url = "${version_directory_baseUrl}/${canonicalJarName}-${version}-sources.jar.md5"

def jarLocation = "lib/${canonicalJarName}-${version}.jar"

println("Downloading JAR from ${jar_file_url} ...")
IOUtils.copy(drl.getResource(jar_file_url).inputStream, new FileOutputStream(jarLocation))
verifyMd5(jarLocation, jar_md5_url)

def sourcesLocation = "lib/${canonicalJarName}-${version}-sources.zip"

println("Attempting to download SOURCES from ${src_file_url} ...")
try {
	IOUtils.copy(drl.getResource(src_file_url).inputStream, new FileOutputStream(sourcesLocation))
	verifyMd5(sourcesLocation, src_md5_url)
} catch (FileNotFoundException e) {
	println("Sources not available.")
}

println("Finished")

def verifyMd5(fileLocation, md5location) {

	def drl = new DRL()
	
	println("Verifying MD5 hash ...")
	def md5FileContent = IOUtils.toString(drl.getResource(md5location).inputStream)

	def matcher = md5FileContent =~ /^([a-z0-9]{32})/
	matcher.find()
	def md5hash = matcher.group(1)

	def jarContent = IOUtils.toByteArray(drl.getResource("file:${fileLocation}").inputStream)
	def jarMd5hash = DigestUtils.md5Hex(jarContent)

	assert md5hash == jarMd5hash

}